using System.Collections;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Be.Timvw.Framework.ComponentModel
{
    [TestClass]
    public class WhenSortingOnSortableBindingLists
    {
        [TestMethod]
        public void ShouldSortByAddressDescending()
        {
            IBindingList bindingList = SortableBindingListFactory.Create();

            IList sortedByAddressDescending = new object[]
            {
                bindingList[2],
                bindingList[1],
                bindingList[0]
            };
            
            PropertyDescriptor propertyDescriptor = PropertyDescriptorHelper.Get(bindingList[0], "Address");
            bindingList.ApplySort(propertyDescriptor, ListSortDirection.Descending);
            AssertSortableBindingList.HaveSameElements(sortedByAddressDescending, bindingList);
        }

        [TestMethod]
        public void ShouldBeAbleToReusePropertyComparerIfSortIsAppliedForSecondTime()
        {
            IBindingList bindingList = SortableBindingListFactory.Create();

            IList sortedByAddressDescneding = new object[]
            {
                bindingList[2],
                bindingList[1],
                bindingList[0]
            };
            
            PropertyDescriptor propertyDescriptor = PropertyDescriptorHelper.Get(bindingList[0], "Address");
            bindingList.ApplySort(propertyDescriptor, ListSortDirection.Descending);
            bindingList.ApplySort(propertyDescriptor, ListSortDirection.Descending);
            AssertSortableBindingList.HaveSameElements(sortedByAddressDescneding, bindingList);
        }

        [TestMethod]
        public void ShouldSortByAddressAscending()
        {
            IBindingList bindingList = SortableBindingListFactory.Create();

            IList sortedByAddressAscending = new object[]
            {
                bindingList[0],
                bindingList[1],
                bindingList[2]
            };
            
            PropertyDescriptor propertyDescriptor = PropertyDescriptorHelper.Get(bindingList[0], "Address");
            bindingList.ApplySort(propertyDescriptor, ListSortDirection.Ascending);
            AssertSortableBindingList.HaveSameElements(sortedByAddressAscending, bindingList);
        }

        [TestMethod]
        public void ShouldSortByIdAscending()
        {
            IBindingList bindingList = SortableBindingListFactory.Create();

            IList sortedByIdAscending = new object[]
            {
                bindingList[0],
                bindingList[1],
                bindingList[2]
            };
            
            PropertyDescriptor propertyDescriptor = PropertyDescriptorHelper.Get(bindingList[0], "Id");
            bindingList.ApplySort(propertyDescriptor, ListSortDirection.Ascending);
            AssertSortableBindingList.HaveSameElements(sortedByIdAscending, bindingList);
        }

        [TestMethod]
        public void ShouldSortByIdDescending()
        {
            IBindingList bindingList = SortableBindingListFactory.Create();

            IList sortedByIdDescending = new object[]
            {
                bindingList[2],
                bindingList[1],
                bindingList[0]
            };
            
            PropertyDescriptor propertyDescriptor = PropertyDescriptorHelper.Get(bindingList[0], "Id");
            bindingList.ApplySort(propertyDescriptor, ListSortDirection.Descending);
            AssertSortableBindingList.HaveSameElements(sortedByIdDescending, bindingList);
        }

        [TestMethod]
        public void ShouldSetSortDirectionCore()
        {
            IBindingList bindingList = SortableBindingListFactory.Create();
            PropertyDescriptor propertyDescriptor = PropertyDescriptorHelper.Get(bindingList[0], "Id");
            bindingList.ApplySort(propertyDescriptor, ListSortDirection.Descending);
            ListSortDirection actual = bindingList.SortDirection;
            ListSortDirection expected = ListSortDirection.Descending;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ShouldBeAbleToSortOnPropertiesOfSameType()
        {
            IBindingList bindingList = SortableBindingListFactory.Create();

            IList sortedByFirstNameAscending = new object[]
            {
                bindingList[0],
                bindingList[1],
                bindingList[2]
            };

            IList sortedByFirstNameDescending = new object[]
            {
                bindingList[2],
                bindingList[1],
                bindingList[0]
            };

            IList sortedByLastNameAscending = new object[]
            {
                bindingList[1],
                bindingList[2],
                bindingList[0]
            };

            IList sortedByLastNameDescending = new object[]
            {
                bindingList[0],
                bindingList[2],
                bindingList[1]
            };

            PropertyDescriptor firstNameProperty = PropertyDescriptorHelper.Get(bindingList[0], "FirstName");
            PropertyDescriptor lastNameProperty = PropertyDescriptorHelper.Get(bindingList[0], "LastName");

            bindingList.ApplySort(lastNameProperty, ListSortDirection.Descending);
            AssertSortableBindingList.HaveSameElements(sortedByLastNameDescending, bindingList);

            bindingList.ApplySort(firstNameProperty, ListSortDirection.Descending);
            AssertSortableBindingList.HaveSameElements(sortedByFirstNameDescending, bindingList);

            bindingList.ApplySort(firstNameProperty, ListSortDirection.Ascending);
            AssertSortableBindingList.HaveSameElements(sortedByFirstNameAscending, bindingList);

            bindingList.ApplySort(lastNameProperty, ListSortDirection.Ascending);
            AssertSortableBindingList.HaveSameElements(sortedByLastNameAscending, bindingList);
        }
    }
}